home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-16 | 19.0 KB | 755 lines | [TEXT/CWIE] |
- // ===========================================================================
- // CGraphGAApp.cp ©1995-97 Timo Eloranta All rights reserved.
- // ===========================================================================
- // The application class - subclassed from LDocApplication.
-
- #include <StandardFile.h>
-
- // -- Core classes
- #include <LApplication.h>
- #include <LCaption.h>
- #include <LClipboard.h>
- #include <LGroupBox.h>
- #include <LGrowZone.h>
- #include <LWindow.h>
- #include <LPicture.h>
- #include <LRadioGroup.h>
- #include <LString.h>
- #include <LTabGroup.h>
-
- // -- Utilities
- #include <UMemoryMgr.h>
- #include <UModalDialogs.h>
- #include <UDrawingState.h>
- #include <URegistrar.h>
- #include <UDesktop.h>
- #include <UWindows.h>
-
- // -- Grayscale Appearance
- #include <UGALibRegistry.h>
- #include <LGABox.h>
- #include <LGAEditField.h>
- #include <LGAPushButton.h>
- #include <LGARadioButton.h>
- #include <LGACheckbox.h>
- #include <LGAPrimaryBox.h>
- #include <LGAPrimaryGroup.h>
- #include <LGASeparator.h>
- #include <LGADialogBox.h>
-
- #include <PP_Messages.h>
- #include <PP_Resources.h>
-
- #include <profiler.h> // Profiler
-
- #include "CGraphGAApp.h"
- #include "CGraphGADoc.h"
- #include "CGraphWindow.h"
- #include "CGraphPane.h"
- #include "CFitness.h"
-
- #include "CProbDialog.h"
- #include "CSelectionDialog.h"
- #include "CTerminationDialog.h"
- #include "CGeneralDialog.h"
- #include "CEvalDialog.h"
-
- #include "CMyCaption.h"
- #include "MyUtils.h" // FastRandom
-
- #include "CAGASlider.h" // James Jennings' grayscale slider class
-
- #include "GraphGA_PaneIDs.h"
-
-
- // ===========================================================================
- // • Main Program
- // ===========================================================================
-
- void
- main( void )
- {
- #if __profile__
- if (! ProfilerInit( collectDetailed, bestTimeBase, 130, 12 )) {
- ProfilerSetStatus( false );
- #endif
-
- #ifdef Debug_Throw // Set Debugging options
- gDebugThrow = debugAction_Alert;
- #endif
- #ifdef Debug_Signal
- gDebugSignal = debugAction_Alert;
- #endif
-
- InitializeHeap(3);
- UQDGlobals::InitializeToolbox( &qd );
-
- FastRandom(0); // Initialize the randomizer
-
- new LGrowZone(20000);
-
- CGraphGAApp theApp; // Create an instance of our app class...
- theApp.Run(); // ...and run it.
-
- #if __profile__
- ProfilerDump("\pTimGA.prof");
- ProfilerTerm();
- }
- #endif
- }
-
- // ---------------------------------------------------------------------------
- // • CGraphGAApp
- //
- // Called by: main
- // ---------------------------------------------------------------------------
- // Constructor
-
- CGraphGAApp::CGraphGAApp()
- {
- SetDefaults();
- RegisterClasses();
-
- AddAttachment(new LClipboard); // Create and attach a clipboard object
- }
-
- // ---------------------------------------------------------------------------
- // • Initialize
- //
- // Called by: LApplication::Run
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::Initialize()
- {
- SetDocToBeShot( false );
-
- mWindow = (CGraphWindow*) // Create
- CGraphWindow::CreateWindow( WIND_GraphGADoc, this ); // main window
-
- ThrowIfNil_( mWindow );
- InitForNoGraph();
-
- mWindow -> Show();
- }
-
- // ---------------------------------------------------------------------------
- // • InitForNoGraph (PRIVATE)
- //
- // Called by: CGraphGAApp::CGraphGAApp
- // CGraphGAApp::RemoveDoc
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::InitForNoGraph()
- {
- CGraphPane *theGraphPane = mWindow -> GetGraphPane();
-
- mWindow -> SetDescriptor( "\pTimGA" );
-
- mWindow -> UpdateGraphInfo( );
- mWindow -> UpdatePopInfo( true );
- mWindow -> UpdateIterStateInfo( );
- mWindow -> UpdateBestInfo( true );
-
- theGraphPane -> SetGraph( nil );
- theGraphPane -> Refresh();
-
- mDoc = nil;
-
- SwitchTarget( theGraphPane );
- }
-
- // ---------------------------------------------------------------------------
- // • ~CGraphGAApp
- // ---------------------------------------------------------------------------
- // Destructor.
-
- CGraphGAApp::~CGraphGAApp()
- {
- if ( mDoc )
- RemoveDoc();
-
- if ( mWindow )
- delete mWindow;
- }
-
- // ---------------------------------------------------------------------------
- // • RemoveDoc (PRIVATE)
- //
- // Called by: CGraphGAApp::~CGraphGAApp
- // CGraphGAApp::ObeyCommand
- // CGraphGAApp::OpenDocument
- // CGraphGAApp::MakeNewDocument
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::RemoveDoc()
- {
- if (! mDoc ) {
- SysBeep(1); // This should *never* happen
- } else {
- if ( mWindow )
- mWindow -> ResetSuperCommanderToApp();
-
- delete mDoc;
-
- InitForNoGraph();
- }
- }
-
- // ---------------------------------------------------------------------------
- // • ObeyCommand
- //
- // Called by: LCommander::ProcessCommand
- // ---------------------------------------------------------------------------
- // Respond to commands
-
- Boolean
- CGraphGAApp::ObeyCommand(
- CommandT inCommand,
- void *ioParam)
- {
- Boolean cmdHandled = true;
-
- switch (inCommand) {
-
- case cmd_New:
- if ( AskNewGraphSize() )
- cmdHandled = LDocApplication::ObeyCommand( cmd_New, ioParam );
- break;
-
- case cmd_CloseGraph:
- if ( mDoc )
- RemoveDoc();
- break;
-
- case cmd_Quit:
- if ( mDoc )
- RemoveDoc();
- cmdHandled = LDocApplication::ObeyCommand( cmd_Quit, ioParam );
- break;
-
- case cmd_General:
- CGeneralDialog *theGDialog =
- (CGeneralDialog *) LWindow::CreateWindow( WIND_General, this);
-
- theGDialog -> InitDialog();
- theGDialog -> SetValues( mGeneral );
-
- theGDialog -> Show();
- break;
-
- case cmd_SetGeneral:
- SetGeneralFromDialog( (SLGADialogResponse *) ioParam, 0 );
-
- mWindow -> UpdateGraphInfo( );
- mWindow -> UpdatePopInfo( true );
-
- (mWindow -> GetGraphPane()) -> SetGraph( nil );
- (mWindow -> GetGraphPane()) -> Refresh();
- break;
-
- case cmd_Selection:
- CSelectionDialog *theSDialog =
- (CSelectionDialog *) LWindow::CreateWindow( WIND_Select, this);
-
- theSDialog -> InitDialog();
- theSDialog -> SetValues( mSelection, mGeneral.sizePop );
- theSDialog -> Show();
- break;
-
- case cmd_SetSelection:
- SetSelFromDialog( (SLGADialogResponse *) ioParam);
- break;
-
- case cmd_Recombination:
- CProbDialog *thePDialog =
- (CProbDialog *) LWindow::CreateWindow( WIND_Prob, this);
-
- thePDialog -> InitDialog();
- thePDialog -> SetValues( mCrossoverProb, mMutationProb );
- thePDialog -> Show();
- break;
-
- case cmd_SetProbabilities:
- SetProbsFromDialog( (SLGADialogResponse *) ioParam);
- if ( mDoc )
- mDoc -> SetPopProbabilities( mCrossoverProb, mMutationProb );
- break;
-
- case cmd_Termination:
- CTerminationDialog *theTDialog =
- (CTerminationDialog *) LWindow::CreateWindow( WIND_Terminate, this);
-
- theTDialog -> InitDialog();
- theTDialog -> SetValues( mTermination );
- theTDialog -> Show();
- break;
-
- case cmd_SetTermination:
- SetTerFromDialog( (SLGADialogResponse *) ioParam);
- if ( mDoc )
- mDoc -> SetPopTermination( mTermination );
- break;
-
- case cmd_Evaluation:
- CEvalDialog *theEDialog =
- (CEvalDialog *) LWindow::CreateWindow( WIND_Evaluate, this);
-
- theEDialog -> InitDialog();
- theEDialog -> SetValues( mEvaluation );
- theEDialog -> Show();
- break;
-
- case cmd_SetEvaluation:
- SetEvalFromDialog( (SLGADialogResponse *) ioParam);
- break;
-
- default:
- cmdHandled = LDocApplication::ObeyCommand(inCommand, ioParam);
- break;
- }
-
- return cmdHandled;
- }
-
- // ---------------------------------------------------------------------------
- // • FindCommandStatus
- //
- // Called by: LCommander::ProcessCommandStatus
- // ---------------------------------------------------------------------------
- // Pass back whether a Command is enabled and/or marked (in a Menu)
-
- void
- CGraphGAApp::FindCommandStatus(
- CommandT inCommand,
- Boolean &outEnabled,
- Boolean &outUsesMark,
- Char16 &outMark,
- Str255 outName)
- {
- outUsesMark = false;
-
- switch (inCommand) {
-
- case cmd_CloseGraph:
- outEnabled = false; // See CGraphGADoc::FindCommandStatus !!
- break;
-
- case cmd_Open:
- case cmd_New:
- case cmd_General:
- case cmd_Selection:
- case cmd_Recombination:
- case cmd_Termination:
- case cmd_Evaluation:
- outEnabled = true;
- break;
-
- default:
- LDocApplication::FindCommandStatus(inCommand, outEnabled,
- outUsesMark, outMark, outName);
- break;
- }
- }
-
- // ---------------------------------------------------------------------------
- // • ShowAboutBox
- //
- // Called by: LApplication::ObeyCommand
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::ShowAboutBox()
- {
- StDialogHandler theHandler( WIND_NewAbout, this);
- LWindow *theDialog = theHandler.GetDialog();
-
- if ( theDialog ) {
- while ( true ) {
- MessageT hitMessage = theHandler.DoDialog();
-
- if ( hitMessage == msg_OK )
- break;
- }
- } else {
- UDesktop::Deactivate();
- ::Alert(ALRT_About, nil);
- UDesktop::Activate();
- }
- }
-
- // ---------------------------------------------------------------------------
- // • OpenDocument
- //
- // Called by: CGraphGAApp::ChooseDocument
- // LDocApplication::SendAEOpenDoc
- // LDocApplication::DoAEOpenOrPrintDoc
- // ---------------------------------------------------------------------------
- // Create a new graph "document" from a graph file
-
- void
- CGraphGAApp::OpenDocument(
- FSSpec *inMacFSSpec)
- {
- if ( mDoc )
- RemoveDoc();
-
- mDoc = new CGraphGADoc( this, inMacFSSpec);
-
- if ( mDocShouldGetShot ) {
- RemoveDoc();
- SetDocToBeShot( false );
- } else
- SwitchTarget( mWindow -> GetGraphPane() );
- }
-
- // ---------------------------------------------------------------------------
- // • MakeNewDocument
- //
- // Called by: LDocApplication::SendAECreateDocument
- // LDocApplication::HandleCreateElementEvent
- // ---------------------------------------------------------------------------
- // Create a new Document with RANDOM graph...
-
- LModelObject*
- CGraphGAApp::MakeNewDocument()
- {
- if ( mDoc )
- RemoveDoc();
-
- mDoc = new CGraphGADoc( this, nil);
-
- SwitchTarget( mWindow -> GetGraphPane() );
-
- return mDoc;
- }
-
- // ---------------------------------------------------------------------------
- // • ChooseDocument
- //
- // Called by: LDocApplication::ObeyCommand
- // ---------------------------------------------------------------------------
- // Prompt the user to select a graph file to open
-
- void
- CGraphGAApp::ChooseDocument()
- {
- StandardFileReply macFileReply;
- SFTypeList typeList;
-
- UDesktop::Deactivate();
- typeList[0] = FileType_GraphGA;
- ::StandardGetFile( nil, 1, typeList, &macFileReply);
- UDesktop::Activate();
- if (macFileReply.sfGood) {
- OpenDocument( &macFileReply.sfFile);
- }
- }
-
- // ---------------------------------------------------------------------------
- // • AskNewGraphSize (PRIVATE)
- //
- // Called by: CGraphGAApp::ObeyCommand
- // ---------------------------------------------------------------------------
-
- Boolean
- CGraphGAApp::AskNewGraphSize()
- {
- StDialogHandler theHandler( WIND_NewGraph, this);
- LWindow *theDialog = theHandler.GetDialog();
- Int32 theNodeQty, theEdgeQty, theEdgeMax;
-
- LGAEditField *theNodes = (LGAEditField*) theDialog->FindPaneByID( edit_Nodes );
- theNodes -> SetValue( mNewGraphNodes );
- theNodes -> SelectAll();
- theDialog -> SetLatentSub( theNodes );
-
- LGAEditField *theEdges = (LGAEditField*) theDialog->FindPaneByID( edit_Edges );
- theEdges -> SetValue( mNewGraphEdges );
-
- theDialog->Show();
-
- while ( true ) { // Let DialogHandler process events
- MessageT hitMessage = theHandler.DoDialog();
-
- if ( hitMessage == msg_Cancel ) {
- return false;
-
- } else if ( hitMessage == msg_OK ) {
- theNodeQty = theNodes -> GetValue();
- theEdgeQty = theEdges -> GetValue();
-
- // The maximum number of edges depends on the quantity of nodes.
- theEdgeMax = ( theNodeQty % 2L == 0L ) ?
- theNodeQty * ((theNodeQty / 2) - 1) + (theNodeQty / 2) :
- theNodeQty * (theNodeQty / 2);
-
- if ( theNodeQty < 1 ) {
- UDesktop::Deactivate();
- ::StopAlert( ALRT_TooFewNodes, nil );
- UDesktop::Activate();
- } else if ( theEdgeQty > theEdgeMax ) {
- LStr255 theParam0( theNodeQty );
- LStr255 theParam1( theEdgeMax );
- UDesktop::Deactivate();
- ::ParamText( theParam0, theParam1, "\p", "\p");
- ::StopAlert( ALRT_TooManyEdges, nil );
- UDesktop::Activate();
- } else if ( GridSizeOK( mGeneral.sizeGrid, theNodeQty )) {
- mNewGraphNodes = theNodeQty;
- mNewGraphEdges = theEdgeQty;
- break;
- }
- }
- }
- return true;
- }
-
- // ---------------------------------------------------------------------------
- // • SetProbsFromDialog (PRIVATE)
- //
- // Called by: CGraphGAApp::ObeyCommand
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::SetProbsFromDialog(
- SLGADialogResponse *inResponse )
- {
- ((CProbDialog *) inResponse -> dialogBox)
- -> GetValues( mCrossoverProb, mMutationProb );
-
- delete inResponse -> dialogBox;
- }
-
- // ---------------------------------------------------------------------------
- // • SetSelFromDialog
- //
- // Called by: CGraphGAApp::ObeyCommand
- // CGraphGADoc::ObeyCommand
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::SetSelFromDialog(
- SLGADialogResponse *inResponse )
- {
- ((CSelectionDialog *) inResponse -> dialogBox)
- -> GetValues( mSelection );
-
- delete inResponse -> dialogBox;
- }
-
- // ---------------------------------------------------------------------------
- // • SetTerFromDialog (PRIVATE)
- //
- // Called by: CGraphGAApp::ObeyCommand
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::SetTerFromDialog(
- SLGADialogResponse *inResponse )
- {
- ((CTerminationDialog *) inResponse -> dialogBox)
- -> GetValues( mTermination );
-
- delete inResponse -> dialogBox;
- }
-
- // ---------------------------------------------------------------------------
- // • SetEvalFromDialog (PRIVATE)
- //
- // Called by: CGraphGAApp::ObeyCommand
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::SetEvalFromDialog(
- SLGADialogResponse *inResponse )
- {
- ((CEvalDialog *) inResponse -> dialogBox)
- -> GetValues( mEvaluation );
-
- CFitness::SetEvalStruct( &mEvaluation );
-
- delete inResponse -> dialogBox;
- }
-
- // ---------------------------------------------------------------------------
- // • SetGeneralFromDialog
- //
- // Called by: CGraphGAApp::ObeyCommand
- // /* CGraphGADoc::ObeyCommand */
- // ---------------------------------------------------------------------------
-
- //Boolean
- void
- CGraphGAApp::SetGeneralFromDialog(
- SLGADialogResponse *inResponse,
- Int16 /* inNodes */ )
- {
- // Int16 theOldGridSize = mGeneral.sizeGrid;
- // Int16 theOldPopSize = mGeneral.sizePop;
-
- ((CGeneralDialog *) inResponse -> dialogBox)
- -> GetValues( mGeneral );
-
- delete inResponse -> dialogBox;
- /*
- if (! inNodes )
- return false;
- else {
- if ( inNodes > ( mGeneral.sizeGrid * mGeneral.sizeGrid - 1 )) {
- UDesktop::Deactivate();
- ::StopAlert( ALRT_TooSmallGrid, nil );
- UDesktop::Activate();
- mGeneral.sizeGrid = theOldGridSize;
- }
-
- // The value we return reports whether the population should
- // be reinitialized because either the size of the population
- // or the grid has changed...
-
- if ( mGeneral.sizeGrid == theOldGridSize &&
- mGeneral.sizePop == theOldPopSize )
- return false;
- else
- return true;
- }
- */
- }
-
- // ---------------------------------------------------------------------------
- // • EventSuspend (PRIVATE, OVERRIDE)
- //
- // Called by: LEventDispatcher::EventOS
- // ---------------------------------------------------------------------------
- // Respond to a Suspend event
-
- void
- CGraphGAApp::EventSuspend(
- const EventRecord& inMacEvent )
- {
- GetTarget() -> ObeyCommand( cmd_IterSuspend, nil );
-
- LEventDispatcher::EventSuspend( inMacEvent ); // Call normal behaviour !!
- }
-
- // ---------------------------------------------------------------------------
- // • EventResume (PRIVATE, OVERRIDE)
- //
- // Called by: LEventDispatcher::EventOS
- // ---------------------------------------------------------------------------
- // Respond to a Resume event
-
- void
- CGraphGAApp::EventResume(
- const EventRecord& inMacEvent )
- {
- LEventDispatcher::EventResume( inMacEvent ); // Call normal behaviour !!
-
- GetTarget() -> ObeyCommand( cmd_IterResume, nil );
- }
-
- // ---------------------------------------------------------------------------
- // • SetDefaults (PRIVATE)
- //
- // Called by: CGraphGAApp::CGraphGAApp
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::SetDefaults()
- {
- mGeneral.sizeGrid = DEFAULT_GRID_SIZE;
- mGeneral.sizePop = DEFAULT_POP_SIZE;
- mGeneral.spendTime = DEFAULT_SPEND_TIME;
-
- mEvaluation.crossingsRule = DEFAULT_CROSSINGS_RULE;
- mEvaluation.multip1 = DEFAULT_MULTIP_1;
- mEvaluation.multip2 = DEFAULT_MULTIP_2;
- mEvaluation.multip3 = DEFAULT_MULTIP_3;
- mEvaluation.multip4 = DEFAULT_MULTIP_4;
- mEvaluation.multip5 = DEFAULT_MULTIP_5;
- mEvaluation.multip6 = DEFAULT_MULTIP_6;
- mEvaluation.multip7 = DEFAULT_MULTIP_7;
-
- CFitness::SetEvalStruct( &mEvaluation );
-
- mNewGraphNodes = DEFAULT_NEW_GRAPH_NODES;
- mNewGraphEdges = DEFAULT_NEW_GRAPH_EDGES;
-
- mCrossoverProb = DEFAULT_CROSSOVER_PROB;
- mMutationProb = DEFAULT_MUTATION_PROB;
-
- mSelection.step = DEFAULT_SELECTION_STEP;
- mSelection.min = DEFAULT_SELECTION_MIN;
- mSelection.autom = DEFAULT_SELECTION_AUTOM;
- mSelection.elitism = DEFAULT_ELITISM;
-
- mTermination.maxGenTotal = DEFAULT_MAX_GEN_TOTAL;
- mTermination.maxGenNoChange = DEFAULT_MAX_GEN_NO_CHANGE;
- mTermination.maxTimeTotal = DEFAULT_MAX_TIME_TOTAL;
- mTermination.maxTimeNoChange = DEFAULT_MAX_TIME_NO_CHANGE;
- mTermination.stopMaxGenTotal = false;
- mTermination.stopMaxGenNoChange = false;
- mTermination.stopMaxTimeTotal = false;
- mTermination.stopMaxTimeNoChange = false;
- mTermination.stopNoCrossings = false;
- }
-
- // ---------------------------------------------------------------------------
- // • RegisterClasses (PRIVATE)
- //
- // Called by: CGraphGAApp::CGraphGAApp
- // ---------------------------------------------------------------------------
-
- void
- CGraphGAApp::RegisterClasses()
- {
- // Register functions to create core PowerPlant classes
-
- RegisterClass_( LCaption );
- RegisterClass_( LPane );
- RegisterClass_( LPicture );
- RegisterClass_( LRadioGroup );
- RegisterClass_( LTabGroup );
- RegisterClass_( LView );
- RegisterClass_( LWindow );
-
- RegisterClass_( CAGASlider );
-
- RegisterClass_( CGraphPane );
- RegisterClass_( CGraphWindow );
- RegisterClass_( CProbDialog );
- RegisterClass_( CSelectionDialog );
- RegisterClass_( CTerminationDialog );
- RegisterClass_( CGeneralDialog );
- RegisterClass_( CEvalDialog );
- RegisterClass_( CMyCaption );
-
- // • APPLE GRAYSCALE APPEARANCE CONTROLS, PANES, VIEWS, and WINDOWS
- // •• CONTROLS
-
- RegisterClass_( LGAPushButton );
- RegisterClass_( LGARadioButton );
- RegisterClass_( LGACheckbox );
-
- // •• PANES & VIEWS
-
- RegisterClass_( LGAPrimaryBox );
- RegisterClass_( LGAPrimaryGroup );
- RegisterClass_( LGASeparator );
- RegisterClass_( LGAEditField );
- RegisterClass_( LGABox );
-
- // •• WINDOWS
-
- RegisterClass_( LGADialogBox );
-
-
- // --- Sort table for faster access
-
- TArray<SClassTableEntry> *classTable = URegistrar::GetClassTable();
-
- classTable -> Sort();
- }
-